﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AdventureWorks.Entities;
using AdventureWorksData.DAO;
using AdventureWorks.Helpers;
using AdventureWorks.Exceptions;

namespace AdventureWorks.Business
{
	public class ProductCategoryBusiness : IBusiness<ProductCategory>, IDisposable
	{
		private readonly IUnitOfWork _db;
		private IEnumerable<ProductCategory> _categories;

		
		public ProductCategoryBusiness()
		{
			_db = new UnitOfWork();
		}

		public ProductCategoryBusiness(IUnitOfWork entityDb)
		{
			_db = entityDb;
		}

		public ProductCategory Get(int id)
		{
			return _db.ProductCategories.Get(id);
		}

		public IEnumerable<ProductCategory> GetList(String sortOrder, String searchString)
		{
			_categories = _db.ProductCategories.Get();
			FilterWithSearchString(searchString);
			SortOrder(sortOrder);

			return _categories;
		}

		private void FilterWithSearchString(string searchString)
		{
			if (!String.IsNullOrEmpty(searchString))
			{
				_categories = _categories.Where(p =>
					CustomComparer.CompareString(
						new String[] {p.ID.ToString(), p.Name, p.productCategory.Name },
						searchString));
			}
		}

		private void SortOrder(string sortOrder)
		{
			switch (sortOrder)
			{
				case "Name Desc":
					_categories = _categories.OrderByDescending(p => p.Name);
					break;
				case "ID":
					_categories = _categories.OrderBy(p => p.ID);
					break;
				case "ID Desc":
					_categories = _categories.OrderByDescending(p => p.ID);
					break;
				case "Modified":
					_categories = _categories.OrderBy(p => p.ModifiedDate);
					break;
				case "Modified Desc":
					_categories = _categories.OrderByDescending(p => p.ModifiedDate);
					break;
				default:
					_categories = _categories.OrderBy(p => p.Name);
					break;
			}
		}

		public void Insert(ProductCategory entity)
		{
			if (entity.Validate())
			{
				_db.ProductCategories.Insert(entity);
			}
			else
			{
				ThrowInvalidException();
			}
		}

		public void Update(ProductCategory entity)
		{
			entity.ModifiedDate = DateTime.Now;
			if (entity.Validate())
			{
				_db.ProductCategories.Update(entity);
			}
			else
			{
				ThrowInvalidException();
			}
		}

		public void Delete(int id)
		{
			_db.ProductCategories.Delete(id);
		}

		public void Save()
		{
			_db.Save();
		}

		public void Dispose()
		{
			_db.Dispose();
		}


		public void ThrowInvalidException()
		{
			throw new BusinessException("Invalid Product Category");
		}
	}
}
